# 装饰器 (Decorators) - 简单示例

# 1. 什么是装饰器
# 装饰器就是使用闭包函数，在闭包函数内调用目标函数，
# 可以达到不改动目标函数的同时，增加额外的功能。

# 装饰器本质上是一个接受函数作为参数并返回函数的高阶函数
# 它利用了闭包的特性，可以访问并操作外层函数的变量

# 2. 简单装饰器示例
def my_decorator(func):
    """一个简单的装饰器"""
    def wrapper():
        print("装饰器：函数执行前的操作")
        func()  # 调用原函数（这里形成了闭包，wrapper可以访问外层函数的func参数）
        print("装饰器：函数执行后的操作")
    return wrapper

# 使用装饰器的方式一：通过@语法糖
@my_decorator
def say_hello():
    print("Hello, World!")

# 相当于 say_hello = my_decorator(say_hello)

print("=== 简单装饰器示例 ===")
say_hello()

# 3. 装饰带参数的函数
def decorator_with_args(func):
    """可以处理带参数函数的装饰器"""
    def wrapper(*args, **kwargs):
        # *args 用于接收位置参数，是一个元组
        # **kwargs 用于接收关键字参数，是一个字典
        print("装饰器：函数调用前")
        print(f"接收到的位置参数 args: {args}")
        print(f"接收到的关键字参数 kwargs: {kwargs}")
        result = func(*args, **kwargs)  # 调用原函数并传递参数
        print("装饰器：函数调用后")
        return result
    return wrapper

@decorator_with_args
def greet(name):
    print(f"你好, {name}!")
    return f"Greeting sent to {name}"

@decorator_with_args
def introduce(name, age, city="北京"):
    print(f"我叫{name}，今年{age}岁，来自{city}")
    return f"Introduction completed for {name}"

print("\n=== 带参数的装饰器示例 ===")
result = greet("张三")
print(f"函数返回值: {result}")

print("\n=== 更复杂的参数示例 ===")
result2 = introduce("李四", 25)
print(f"函数返回值: {result2}")

print("\n=== 带关键字参数的示例 ===")
result3 = introduce("王五", age=30, city="上海")
print(f"函数返回值: {result3}")

# 4. 装饰器的用途
# - 在函数执行前后添加日志
# - 性能测试
# - 权限检查
# - 缓存结果
# - 事务处理等

# 5. 装饰器的工作原理总结
# - 装饰器利用了闭包的特性，内部函数可以访问外部函数的变量
# - @decorator 语法是 func = decorator(func) 的语法糖
# - 装饰器在函数定义时就会执行，而装饰器内部返回的函数在被调用时执行